<!DOCTYPE html>
<html>
<head>
<title>Pinhole Camera Diagram</title>
</head>
<body>
<canvas id="pinholeCanvas" width="550" height="400"></canvas>
<script>
    const canvas = document.getElementById('pinholeCanvas');
    const ctx = canvas.getContext('2d');
    
    // Clear canvas
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;

    // --- Define Coordinates and Dimensions ---
    const yCenter = 180;
    const xObject = 100;
    const xPinhole = 280;
    const xImage = 460;
    
    const hObject = 120; // Total height of the object
    const hImage = hObject * (xImage - xPinhole) / (xPinhole - xObject); // Magnification calculation
    
    const pinholeDiameter = 20;
    
    const boxTop = yCenter - 80;
    const boxBottom = yCenter + 80;
    
    const dimLineY = 320;
    const tickSize = 10;
    const arrowSize = 6;

    // --- Helper function to draw filled arrows ---
    function drawFilledArrow(x, y, direction) {
        ctx.beginPath();
        if (direction === 'up') {
            ctx.moveTo(x, y);
            ctx.lineTo(x - arrowSize, y + arrowSize);
            ctx.lineTo(x + arrowSize, y + arrowSize);
        } else if (direction === 'down') {
            ctx.moveTo(x, y);
            ctx.lineTo(x - arrowSize, y - arrowSize);
            ctx.lineTo(x + arrowSize, y - arrowSize);
        }
        ctx.closePath();
        ctx.fill();
    }
    
    // --- Draw Optical Axis ---
    ctx.beginPath();
    ctx.moveTo(xObject, yCenter);
    ctx.lineTo(xImage, yCenter);
    ctx.stroke();

    // --- Draw Object ---
    ctx.beginPath();
    ctx.moveTo(xObject, yCenter - hObject / 2);
    ctx.lineTo(xObject, yCenter + hObject / 2);
    ctx.stroke();
    drawFilledArrow(xObject, yCenter - hObject / 2, 'up');

    // --- Draw Pinhole, Barrier, and Box ---
    ctx.beginPath();
    // Barrier part with pinhole gap
    ctx.moveTo(xPinhole, boxTop);
    ctx.lineTo(xPinhole, yCenter - pinholeDiameter / 2);
    ctx.moveTo(xPinhole, yCenter + pinholeDiameter / 2);
    ctx.lineTo(xPinhole, boxBottom);
    // Box outline
    ctx.moveTo(xPinhole, boxTop);
    ctx.lineTo(xImage, boxTop);
    ctx.lineTo(xImage, boxBottom);
    ctx.lineTo(xPinhole, boxBottom);
    ctx.stroke();

    // --- Draw Image ---
    ctx.beginPath();
    ctx.moveTo(xImage, yCenter - hImage / 2);
    ctx.lineTo(xImage, yCenter + hImage / 2);
    ctx.stroke();
    drawFilledArrow(xImage, yCenter + hImage / 2, 'down');

    // --- Draw Light Rays ---
    ctx.beginPath();
    // Top of object to bottom of image, crossing at the pinhole center
    ctx.moveTo(xObject, yCenter - hObject / 2);
    ctx.lineTo(xImage, yCenter + hImage / 2);
    // Bottom of object to top of image, crossing at the pinhole center
    ctx.moveTo(xObject, yCenter + hObject / 2);
    ctx.lineTo(xImage, yCenter - hImage / 2);
    ctx.stroke();

    // --- Draw Dimension Lines and Labels ---
    
    // L and P dimension
    ctx.beginPath();
    ctx.moveTo(xObject, dimLineY);
    ctx.lineTo(xImage, dimLineY);
    // Ticks
    ctx.moveTo(xObject, dimLineY - tickSize / 2);
    ctx.lineTo(xObject, dimLineY + tickSize / 2);
    ctx.moveTo(xImage, dimLineY - tickSize / 2);
    ctx.lineTo(xImage, dimLineY + tickSize / 2);
    ctx.stroke(); // Stroke the main line and end ticks
    
    // Center divider tick ('+')
    ctx.beginPath();
    ctx.moveTo(xPinhole, dimLineY - tickSize);
    ctx.lineTo(xPinhole, dimLineY + tickSize);
    ctx.stroke();
    ctx.save();
    ctx.lineWidth = 4; // Make horizontal part of the '+' thicker
    ctx.beginPath();
    const arrowTickWidth = 6;
    ctx.moveTo(xPinhole - arrowTickWidth, dimLineY);
    ctx.lineTo(xPinhole + arrowTickWidth, dimLineY);
    ctx.stroke();
    ctx.restore();
    
    // 'd' dimension
    const xDimD = 255;
    const yTop = yCenter - pinholeDiameter / 2;
    const yBottom = yCenter + pinholeDiameter / 2;
    ctx.beginPath();
    ctx.moveTo(xDimD, yTop);
    ctx.lineTo(xDimD, yBottom);
    // Ticks for 'd'
    ctx.moveTo(xDimD, yTop);
    ctx.lineTo(xDimD - tickSize, yTop);
    ctx.moveTo(xDimD, yBottom);
    ctx.lineTo(xDimD - tickSize, yBottom);
    ctx.stroke();
    
    // --- Draw Text Labels ---
    ctx.font = 'italic bold 22px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillText('L', (xObject + xPinhole) / 2, dimLineY - 5);
    ctx.fillText('P', (xPinhole + xImage) / 2, dimLineY - 5);
    
    ctx.font = 'italic 22px serif';
    ctx.textAlign = 'right';
    ctx.textBaseline = 'middle';
    ctx.fillText('d', xDimD - 15, yCenter);

    ctx.font = 'bold 22px serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    ctx.fillText('Fig. 2.66', canvas.width / 2, dimLineY + 30);

</script>
</body>
</html>